#include "MeshView.hpp"
#include "MeshAlgorithm.hpp"
#include "SelfIntersectionView.hpp"
#include "gl.hpp"
#include "SelectTexture.hpp"

#include "ViewScene.hpp"
static SelfIntersectionView* thisPtr = 0;
SelfIntersectionView::SelfIntersectionView()
{
   thisPtr = this;
   mEnabled = false;
   ViewScene::SelectedMeshChanged.connect( boost::bind(&SelfIntersectionView::UpdateIntersections, this) );
   MEvents.Signal("View Self Intersections").connect( SelfIntersectionView::HandleToggle );
}
void SelfIntersectionView::HandleToggle(boost::many& aArgs)
{
   thisPtr->SetEnabled(!thisPtr->mEnabled);
}
void SelfIntersectionView::UpdateIntersections()
{
   if (! mEnabled) return;
   mIntersectedFaces.clear();
   MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
   if (!meshPtr) return;
   MeshAlgorithm::FindIntersectingFaces(meshPtr->mMesh.GetCreaseMesh(), mIntersectedFaces);
}
void SelfIntersectionView::SetEnabled(bool aisEnabled)
{
   if (aisEnabled != mEnabled)
   {
      mEnabled = aisEnabled;
      mIntersectedFaces.clear();
      if (mEnabled)
      {
         UpdateIntersections();
      }
   }
}

void SelfIntersectionView::Draw()
{
   if (!mEnabled) return;
   MeshView* meshPtr = ViewScene::GetInstance().GetSelectedMesh();
   if (!meshPtr) return;

   gl::Blend state2;
   gl::NoLighting state3;
   ViewScene::GetInstance().LoadProjection(1/1.0005f);
   glDisable(GL_CULL_FACE);
   glColor4f(1,1,1,.4);
   SelectTexture::Bind();
   glBegin(GL_TRIANGLES);
   VertexList& verts = *meshPtr->mMesh.verts;
   float texCoords[3][2] = { { 0,0 }, { 3, 0}, {0, 3} };
   for (size_t i = 0; i < mIntersectedFaces.size(); ++i)
   {
      int fi = mIntersectedFaces[i];
      Face& f = meshPtr->mMesh.crease_faces[fi];
      for (int v = 0; v < 3; ++v)
      {
         glTexCoord2f(texCoords[v][0], texCoords[v][1]);
         gl::Vertex(verts[f.vertex[v]]);
      }
   }
   glEnd();
   SelectTexture::Unbind();
   glEnable(GL_CULL_FACE);
   ViewScene::GetInstance().LoadProjection(1);
}
